#include <fstream>

#include <iostream>
#include <string.h>
#include <string>

using namespace std;

const char FileName[] = "os.txt";

const char NullName[] = "0000000000000";

const int DirLen = 1;

const short SSNum = -1; //super block num

enum FileSpec
{
  NORMAL,
  DIR,
  BLOCK,
  PIP
}; //0,1,2,3

//i节点结构信息

struct INode
{

  FileSpec fileSpec;

  short iaddr[13];

  int fileLength;

  int linkCount;
};

struct DirChild

{

  char filename[14];

  short i_BNum;
};

struct DirNode
{

  DirChild childItem[64];

  short DirCount;
};

short SS[51]; //超级栈,指针为SS[0]

short freeBlockNum = 0; //当前可用盘快所在组记录的盘快号

short freeTotalB = 20450;

short freeDirNode[29]; //可用索引节点栈

short freeDirCount = 30; //索引节点栈指针

short currDirNum; //当前目录所在的磁盘号

short currINum;

DirNode *currDir;

INode *iNode;

//================================================================

//函数描述：创建20M磁盘

//入口参数：无

//返回值：　无

//===============================================================

void Format()

{

  cout << "系统正在初始化......" << endl;

  // 打开文件

  FILE *f = fopen(FileName, "w+");

  if (f == NULL)

  {

    cout << "程序创建错误，请重新输入" << endl;

    return;
  }

  for (int i = 0; i < 20971520; i++) //20971520=20Mb,暂时2mb

    fprintf(f, "%c", '0');

  // 关闭文件

  fclose(f);
}

//================================================================

//函数描述：数组赋值

//入口参数：无

//返回值：　无

//===============================================================

void ArrarEqual(short arr[51], short begin, short end)

{

  for (short i = 0; i < end - begin + 1; i++)

    arr[50 - i] = begin + i;
}

//================================================================

//函数描述：数组赋值

//入口参数：无

//返回值：　无

//===============================================================

/*

void BWrite(short arr[51],short diskNum){

           FILE *f = fopen(FileName, "r+");

           if (f == NULL)

           {

           cout<<"写文件处错误，请重新输入"<<endl;

           return ;

           }

           //设置文件指针

           if(fseek(f,1024*diskNum,0))

                      cout<<"文件指针错误"<<endl;

           fwrite(arr,sizeof(short),51,f);

           fclose(f);

          

          

}

*/

//================================================================

//函数描述：重构BWrite，实现一个数组的写入

//入口参数：无

//返回值：　无

//===============================================================

void BWrite(short arr[51], short diskNum)
{

  FILE *f = fopen(FileName, "r+");

  if (f == NULL)

  {

    cout << "写文件处错误，请重新输入" << endl;

    return;
  }

  //设置文件指针

  if (fseek(f, 1024 * diskNum, 0))

    cout << "文件指针错误" << endl;

  fwrite(arr, sizeof(short), 51, f);

  fclose(f);
}

//================================================================

//函数描述：重构BWrite，实现一个数组的写入,数组长度不确定

//入口参数：无

//返回值：　无

//===============================================================

void BWriteArr(short arr[512], short diskNum)
{

  FILE *f = fopen(FileName, "r+");

  if (f == NULL)

  {

    cout << "写文件处错误，请重新输入" << endl;

    return;
  }

  //设置文件指针

  if (fseek(f, 1024 * diskNum, 0))

    cout << "文件指针错误" << endl;

  fwrite(arr, sizeof(short), 512, f);

  fclose(f);
}

//================================================================

//函数描述：重构BWrite，实现一个数组的写入

//入口参数：无

//返回值：　无

//===============================================================

void MyBWrite(short arr[51], short diskNum)
{

  FILE *f = fopen(FileName, "r+");

  if (f == NULL)

  {

    cout << "写文件处错误，请重新输入" << endl;

    return;
  }

  //设置文件指针

  if (fseek(f, 1024 * diskNum, 0))

    cout << "文件指针错误" << endl;

  for (short i = 0; i < 51; i++)

    fprintf(f, "%d", arr[i]);

  fclose(f);
}

//================================================================

//函数描述：从磁盘中读出数组

//入口参数：无

//返回值：　无

//===============================================================

void MyBRead(short arr[51], short diskNum)
{

  FILE *f = fopen(FileName, "r+");

  if (f == NULL)

  {

    cout << "读文件处错误，请重新输入" << endl;

    return;
  }

  //设置文件指针

  if (fseek(f, 1024 * diskNum, 0))

    cout << "文件指针错误" << endl;

  for (short i = 0; i < 51; i++)

    fscanf(f, "%d", &arr[i]);

  fclose(f);
}

//================================================================

//函数描述：从磁盘中读出iNode节点

//入口参数：无

//返回值：　无

//===============================================================

void BRead(INode *iNode, short diskNum)
{

  FILE *f = fopen(FileName, "r+");

  if (f == NULL)

  {

    cout << "写文件处错误，请重新输入" << endl;

    return;
  }

  //设置文件指针

  if (fseek(f, 1024 * diskNum, 0))

    cout << "文件指针错误" << endl;

  fscanf(f, "%d", &iNode->fileLength);

  int temp = int(fgetc(f));

  switch (temp)
  {

  case 0:

    iNode->fileSpec = NORMAL;

    break;

  case 1:

    iNode->fileSpec = DIR;

    break;

  case 2:

    iNode->fileSpec = BLOCK;

    break;

  case 3:

    iNode->fileSpec = PIP;

    break;
  }

  fread(iNode->iaddr, 2, 13, f);

  fscanf(f, "%d", &iNode->linkCount);

  fclose(f);
}

//================================================================

//函数描述：从磁盘中读出数组

//入口参数：无

//返回值：　无

//===============================================================

void BRead(short arr[51], short diskNum)
{

  FILE *f = fopen(FileName, "r+");

  if (f == NULL)

  {

    cout << "读文件处错误，请重新输入" << endl;

    return;
  }

  //设置文件指针

  if (fseek(f, 1024 * diskNum, 0))

    cout << "文件指针错误" << endl;

  fread(arr, sizeof(short), 51, f);

  fclose(f);
}

//================================================================

//函数描述：从磁盘中读出数组, 放入到iNOde中

//入口参数：无

//返回值：　无

//===============================================================

void BReadArr(short arr[512], short diskNum)
{

  FILE *f = fopen(FileName, "r+");

  if (f == NULL)

  {

    cout << "读文件处错误，请重新输入" << endl;

    return;
  }

  //设置文件指针

  if (fseek(f, 1024 * diskNum, 0))

    cout << "文件指针错误" << endl;

  fread(arr, sizeof(short), 512, f);

  fclose(f);
}

//================================================================

//函数描述：写入一个目录项

//入口参数：无

//返回值：　无

//===============================================================

void BWrite(DirNode *currDir, short diskNum)
{

  FILE *f = fopen(FileName, "r+");

  if (f == NULL)

  {

    cout << "写文件处错误，请重新输入" << endl;

    return;
  }

  //设置文件指针

  if (fseek(f, long(1024 * diskNum), 0))

    cout << "文件指针错误" << endl;

  for (int i = 0; i < 64; i++)

  {

    fprintf(f, "%hd", currDir->childItem[i].i_BNum);

    fputs(currDir->childItem[i].filename, f);
  }

  fclose(f);
}

//================================================================

//函数描述：写入一个iNode

//入口参数：无

//返回值：　无

//===============================================================

void BWrite(INode *iNode, short diskNum)
{

  FILE *f = fopen(FileName, "r+");

  if (f == NULL)

  {

    cout << "写文件处错误，请重新输入" << endl;

    return;
  }

  //设置文件指针

  if (fseek(f, 1024 * diskNum, 0))

    cout << "文件指针错误" << endl;

  fprintf(f, "%d", iNode->fileLength);

  fputc(iNode->fileSpec, f);

  fwrite(iNode->iaddr, 2, 13, f);

  fprintf(f, "%d", iNode->linkCount);

  fclose(f);
}

//================================================================

//函数描述：分配一个空闲的普通快

//入口参数：无

//返回值：　无

//===============================================================

short AssAnEmpty()
{

  short temp;

  if (SS[0] > 1)
  {

    SS[0]--;

    temp = SS[SS[0] + 1];

    //                               SS[SS[0]+1]=-1;

    freeTotalB--; //总剩余数-1

    return temp;
  }
  else
  {

    if (SS[1] == 0)
    {

      cout << "盘片用尽" << endl;

      return -1;
    }

    temp = freeBlockNum;

    freeBlockNum = SS[1];

    BRead(SS, SS[1]);

    if (temp == 0)
    {

      SS[0]--;

      temp = SS[SS[0] + 1];

      //                               SS[SS[0]+1]=-1;
    }

    freeTotalB--;

    return temp;
  }
}

//================================================================

//函数描述：分配一个空闲的目录快

//入口参数：无

//返回值：　无

//===============================================================

short AssAnDir()
{

  if (freeDirCount == 0)
  {

    cout << "无空余目录节点" << endl;

    return -1;
  }

  else
  {

    freeDirCount--;

    short s = freeDirNode[freeDirCount];

    freeDirNode[freeDirCount] = -1;

    return s; //可用索引节点栈
  }
}

//================================================================

//函数描述：创建一个文件节点，并分配INOde和磁盘空间

//入口参数：无

//返回值：　无

//===============================================================

void InitCreate(DirNode *currDir, FileSpec fielSpec, char filename[14], INode *iNode, short diskNum)
{

  //         int blockNum=AssertAnEmpty();

  if (fielSpec == DIR)
  {

    //init dirNode and write

    int blockNum = AssAnDir();

    currDirNum = blockNum;

    for (int i = 0; i < 64; i++)
    {

      strcpy(currDir->childItem[i].filename, "0000000000000");

      currDir->childItem[i].i_BNum = -1;
    }

    BWrite(currDir, blockNum);

    /*

                      //init INode and write

             blockNum=AssertAnEmpty(); 

             iNode->fileLength=DirLen;

             iNode->fileSpec=DIR;

             iNode->iaddr[0]=blockNum;

             iNode->linkCount=1;

             BWrite(iNode,distNum);

             //为文件分配磁盘空间

*/

  } //end  if(fileSpec==DIR)
}

//================================================================

//函数描述：初始化

//入口参数：无

//返回值：　无

//===============================================================

void Init(DirNode *currDir, FileSpec fielSpec, char filename[14], INode *iNode, short diskNum)
{

  InitCreate(currDir, fielSpec, filename, iNode, diskNum);

  BRead(SS, 0);
}

//================================================================

//函数描述：初始化索引栈

//入口参数：无

//返回值：　无

//===============================================================

void Init()
{

  for (int i = 0; i < 30; i++)

    freeDirNode[i] = 30 - i; //可用索引节点栈

  freeDirCount = 30; //索引节点栈指针
}

//================================================================

//函数描述：成组链接初始化

//入口参数：无

//返回值：　无

//===============================================================

void Linkdisk()
{

  //临时空闲栈

  SS[0] = 50;

  ArrarEqual(SS, 31, 80);

  BWrite(SS, 0);

  for (short i = 1; i < 408; i++)
  {

    SS[0] = 50;

    ArrarEqual(SS, i * 50 + 31, i * 50 + 80);

    BWrite(SS, i * 50 + 30);

    BRead(SS, 0);
  }

  ArrarEqual(SS, 408 * 50 + 31, 408 * 50 + 79);

  SS[1] = 0; //49

  BWrite(SS, 408 * 50 + 30);

  cout << "磁盘disk.txt完成创建,大小20MB" << endl;
}

//================================================================

//函数描述：判断一个文件是否存在

//入口参数：无

//返回值：　-1,不存在，文件号

//===============================================================

short IsFileExist(DirNode *currDir, char fileName[14])
{

  for (int i = 0; i < 64; i++)
  {

    if (strcmp(fileName, currDir->childItem[i].filename) == 0)

      return currDir->childItem[i].i_BNum;
  }

  return -1;
}

//================================================================

//函数描述：判断一个文件是一个普通文件

//入口参数：无

//返回值：　-1,不存在，文件号

//===============================================================

bool IsFile(INode *iNode, short diskNum)
{

  BRead(iNode, diskNum);

  if (iNode->fileSpec == NORMAL)

    return true;

  else

    return false;
}

//================================================================

//函数描述：判断一个文件是一个普通文件

//入口参数：无

//返回值：　-1,不存在，文件号

//===============================================================

bool IsDir(INode *iNode, short diskNum)
{

  BRead(iNode, diskNum);

  if (iNode->fileSpec == DIR)

    return true;

  else

    return false;
}

//================================================================

//函数描述：创建一个iNode,并分配磁盘空间

//入口参数：无

//返回值：　无  AssAnEmpty()，BWrite(dirChild,dir[512-i])未实现

//===============================================================

void CreateINode(INode *iNode, FileSpec fileSpec, short linkCount, short length)
{

  iNode->fileSpec = fileSpec;

  iNode->linkCount = linkCount;

  iNode->fileLength = length;

  //为目录磁盘，分配目录节点

  if (fileSpec == DIR)
  {

    iNode->iaddr[0] = AssAnDir();

    return;
  }

  //根据文件长度分配文件磁盘节点

  //直接寻址

  short i;

  i = 10;

  short left = length;

  while (left && i)
  {

    iNode->iaddr[10 - i] = AssAnEmpty();

    left--;

    i--;
  }

  if (left > 0)
  { //一级索引

    i = 512;

    short dir[512];

    iNode->iaddr[10] = AssAnEmpty();

    while (left && i)
    {

      dir[512 - i] = AssAnEmpty();

      i--;

      left--;
    }

    if (i != 0)

      dir[512 - i + 1] = -1; //标志文件结束

    BWriteArr(dir, iNode->iaddr[10]);

    if (left > 0)
    { //二级索引

      short k = 512;

      short j = 512;

      short dirChild[512];

      iNode->iaddr[11] = AssAnEmpty();

      while (left && k)
      { //二级索引1次寻址

        dir[512 - k] = AssAnEmpty();

        while (left && j)
        { //二级索引二次寻址

          dirChild[512 - j] = AssAnEmpty();

          left--;

          j--;
        }

        if (j != 0)

          dir[512 - j + 1] = -1; //标志二级索引二次寻址结束

        BWriteArr(dirChild, dir[512 - k]);

        BWriteArr(dir, iNode->iaddr[11]); //写二级索引一次寻址中盘快记录的一次寻的盘快号

        k--;
      }

      if (k != 0)

        dir[512 - k + 1] = -1; //标志文件结束
    }
  }
}

//================================================================

//函数描述：清空iNode信息,并分配磁盘空间

//入口参数：无

//返回值：　无  AssAnEmpty()，BWrite(dirChild,dir[512-i])未实现

//===============================================================

void CleanINode(INode *iNode)
{

  iNode->fileSpec = PIP;

  iNode->linkCount = -1;

  iNode->fileLength = -1;

  //根据文件长度非配文件磁盘节点

  //直接寻址

  for (short i = 0; i < 13; i++)

    iNode->iaddr[i] = -1;
}

//================================================================

//函数描述：创建一个iNode,并分配磁盘空间

//入口参数：无

//返回值：　无

//===============================================================

void InsertDir(DirNode *currDir, char fileName[14], short blockNum)
{

  strcpy(currDir->childItem[currDir->DirCount].filename, fileName);

  currDir->childItem[currDir->DirCount].i_BNum = blockNum;

  currDir->DirCount++;

  return;
}

//================================================================

//函数描述：存在文件，并分配iNOde节点和磁盘空间

//入口参数：无

//返回值：　无

//===============================================================

void Create(DirNode *currDir, char fileName[14], INode *iNode, short length, FileSpec fileSpec)
{

  int blockNum;

  if (length > freeTotalB)
  {

    cout << "当前文件超出长度" << endl;

    return;
  }

  CreateINode(iNode, fileSpec, 0, length);

  blockNum = AssAnEmpty(); //分配一个空余磁盘存储iNOde

  InsertDir(currDir, fileName, blockNum);

  BWrite(iNode, blockNum);

  CleanINode(iNode);

  BWrite(currDir, currDirNum); //此处
}

//================================================================

//函数描述：创建一个文件，

//入口参数：无

//返回值：　无

//===============================================================

void Mf(DirNode *currDir, char fileName[14], INode *iNode, short length)
{

  int blockNum = IsFileExist(currDir, fileName);

  if (blockNum != -1)
  { //有重名名，进一步判断

    if (IsFile(iNode, blockNum))

      cout << "当前文件已经存在，请重新输入文件名" << endl;
  }
  else
  { //存在文件，为索引文件，或者无重名现象,创建文件，并分配iNOde节点和磁盘空间

    // BRead(iNode,1059);//此处出错

    Create(currDir, fileName, iNode, length, NORMAL);
  }
}

//================================================================

//函数描述：在当前目录创建一个子目录

//入口参数：无

//返回值：　无

//===============================================================

void Md(DirNode *currDir, char fileName[14], INode *iNode, short length)
{

  int blockNum = IsFileExist(currDir, fileName);

  if (blockNum != -1)
  { //有重名名，进一步判断

    if (IsDir(iNode, blockNum))

      cout << "当前目录已经存在，请重新输入目录名" << endl;
  }
  else
  { //存在文件但为普通文件，或者无重名现象。创建文件，并分配iNOde节点和磁盘空间

    Create(currDir, fileName, iNode, length, DIR);

    CleanINode(iNode);
  }

} //================================================================

//函数描述：打开一个文件，

//入口参数：无

//返回值：　无

//===============================================================

void ShowBlockInfo(INode *iNode)
{

  short dir[512];

  short i;

  i = 10;

  short left = iNode->fileLength;

  while (left && i)
  {

    cout << (iNode->fileLength - left) << ":" << iNode->iaddr[10 - i] << "  ";

    left--;

    i--;
  }

  if (left > 0)
  {

    i = 512;

    short dir1[512];

    BReadArr(dir1, iNode->iaddr[10]);

    while (left && i)
    {

      cout << (iNode->fileLength - left) << ":" << dir1[512 - i] << "  ";

      i--;

      left--;
    }
  }

  if (left > 0)
  { //二级索引

    short k = 512;

    short j = 512;

    short dirChild[512];

    BReadArr(dir, iNode->iaddr[11]);

    while (left && k)
    { //二级索引1次寻址

      BReadArr(dirChild, dir[512 - k]);

      while (left && j)
      { //二级索引二次寻址

        cout << (iNode->fileLength - left) << ":" << dirChild[512 - j] << "  ";

        left--;

        j--;
      }

      k--;
    }
  }
}

//================================================================

//函数描述：打开一个文件，

//入口参数：无

//返回值：　无

//===============================================================

void ShowFileInfo(INode *iNode, char fileName[14])
{

  cout << "文件名        " << fileName;

  cout << "      文件类型  ";

  switch (iNode->fileSpec)
  {

  case NORMAL:

    cout << "< 文件 > ";

    break;

  case DIR:

    cout << "< 目录 > ";
    break;

  case BLOCK:

    cout << "< INode节点 > ";
    break;

  case PIP:

    cout << "管道  ";
    break;
  }

  cout << "         " << iNode->fileLength << "KB" << endl;
}

//================================================================

//函数描述：打开一个文件，

//入口参数：无

//返回值：　无

//===============================================================

void Open(DirNode *currDir, char fileName[14], INode *iNode)
{

  int blockNum = IsFileExist(currDir, fileName);

  if (blockNum == -1)
  { //不存在该文件，退出

    cout << "该文件按不存在" << endl;

    return;
  }

  else
  {

    if (IsFile(iNode, blockNum))
    {

      ShowFileInfo(iNode, fileName);

      ShowBlockInfo(iNode);
    }
  }
}

//================================================================

//函数描述：回收一块空余磁盘片

//入口参数：无

//返回值：　无

//===============================================================

void CallBackOne(short diskNum)
{

  freeTotalB++;

  if (SS[0] <= 49)
  {

    SS[0]++;

    SS[SS[0]] = diskNum;
  }
  else
  { //SS[0]==50

    BWrite(SS, freeBlockNum); //将空白的一组回写到上一组记录空闲盘快号的磁盘

    freeBlockNum = SS[1]; //将当前空白的一组第一个盘快作为下一个盘组的记录盘

    //修改超级栈

    SS[1] = diskNum;

    SS[0] = 1;
  }
}

//================================================================

//函数描述：回收文件占用的磁盘

//入口参数：无

//返回值：　无

//===============================================================

void CallBackDisk(INode *iNode)
{

  short i;

  i = 10;

  short left = iNode->fileLength;

  while (left && i)
  { //直接索引回收

    CallBackOne(iNode->iaddr[10 - i]);

    left--;

    i--;
  }

  if (left > 0)
  { //一级索引回收

    i = 512;

    short dir1[512];

    BReadArr(dir1, iNode->iaddr[10]);

    while (left && i)
    {

      CallBackOne(dir1[512 - i]);

      i--;

      left--;
    }

    CallBackOne(iNode->iaddr[10]);
  }

  if (left > 0)
  { //二级索引

    short k = 512;

    short j = 512;

    short dir[512];

    short dirChild[512];

    BReadArr(dir, iNode->iaddr[11]); //二级索引1次寻址

    while (left && k)
    { //二级索引1次寻址

      BReadArr(dirChild, dir[512 - k]);

      while (left && j)
      { //二级索引二次回收

        CallBackOne(dirChild[512 - j]);

        left--;

        j--;
      }

      CallBackOne(dir[512 - k]); //二级索引一次寻址

      k--;
    }

    CallBackOne(iNode->iaddr[11]);
  }
}

//================================================================

//函数描述：回收文件的iNOde节点

//入口参数：无

//返回值：　无

//===============================================================

void CallBackINode(short diskNum)
{

  CallBackOne(diskNum);
}

//================================================================

//函数描述：删除索引中一项

//入口参数：无

//返回值：　-1,不存在，文件号

//===============================================================

void DelDirItem(DirNode *currDir, char fileName[14])
{

  for (int i = 0; i < 64; i++)
  {

    if (strcmp(fileName, currDir->childItem[i].filename) == 0)
    {

      //         currDir->DirCount--;

      strcpy(currDir->childItem[i].filename, NullName);

      currDir->childItem[i].i_BNum = -1;

      return;
    }
  }

  cout << "删除失败" << endl;
}

//================================================================

//函数描述：删除一个文件

//入口参数：无

//返回值：　无

//===============================================================

void Del(DirNode *currDir, char fileName[14], INode *iNode)
{

  short blockNum = IsFileExist(currDir, fileName);

  if (blockNum == -1)
  { //不存在该文件，退出

    cout << "文件不存在，删除失败" << endl;
  }
  else
  {

    if (IsFile(iNode, blockNum))
    {

      CallBackDisk(iNode);

      DelDirItem(currDir, fileName);

      CleanINode(iNode);
    }
    else
    {

      cout << "文件不存在，删除失败" << endl;
    }
  }
}

//================================================================

//函数描述：删除一个目录

//入口参数：无

//返回值：　无

//===============================================================

void Rd(DirNode *currDir, char fileName[14], INode *iNode)
{

  short blockNum = IsFileExist(currDir, fileName);

  if (blockNum == -1)
  { //不存在该文件，退出

    cout << "目录不存在，删除失败" << endl;
  }
  else
  {

    if (IsDir(iNode, blockNum))
    {

      CallBackDisk(iNode);

      DelDirItem(currDir, fileName);

      CleanINode(iNode);
    }
    else
    {

      cout << "目录不存在，删除失败" << endl;
    }
  }
}

//================================================================

//函数描述：显示目录项的内容

//入口参数：无

//返回值：　无

//===============================================================

void Dir(DirNode *currDir, INode *iNode)
{

  for (int i = 0; i < currDir->DirCount; i++)
  {

    if (currDir->childItem[i].i_BNum != -1)
    {

      BRead(iNode, currDir->childItem[i].i_BNum);

      ShowFileInfo(iNode, currDir->childItem[i].filename);
    }

    CleanINode(iNode);
  }
}

//================================================================

//函数描述：销毁资源

//入口参数：无

//返回值：　无

//===============================================================

void exit(DirNode *currDir, INode *iNode)
{

  delete iNode;

  delete currDir;
}

//================================================================

//函数描述：打印版权信息

//入口参数：无

//返回值：　无

//===============================================================

void AuthorMessage()
{

  cout << "==============================================================================" << endl;

  cout << "                            操作系统课程设计" << endl;

  cout << "==============================================================================" << endl;

  printf("单位:        济南大学信息学院计本0601班\n");

  printf("作者:        范海青\n");

  printf("学号:       20061204013\n");

  printf("时间:        2009.4        \n");

  printf("                                         版权所有 翻版必究\n");

  cout << "==============================================================================" << endl;
}

//================================================================

//函数描述：打印版权信息

//入口参数：无

//返回值：　无

//===============================================================

void help() //打印命令及解释

{

  cout << "==============================================================================\n"
       << endl;

  printf("                              命令使用指南\n");

  printf("    1:     mf                                                                        新建文件\n");

  printf("    2:     md                                                                       建立子目录\n");

  printf("    3:     open                                                                   打开文件\n");

  printf("    4:     del                                                                       删除文件\n");

  printf("    5:     rd                                                                         删除目录\n");

  printf("    6:     dir                                                                        显示目录\n");

  printf("    7:     exit                                                                      退出系统\n");

  printf("    8:     cls                                                                        清屏\n");

  cout << "==============================================================================\n"
       << endl;

  cout << "\n请输入命令,回车确认" << endl;
}

int main()
{

  bool run = true;

  int length = 1024;

  char fileName[14];

  char dirName[14];

  int command;

  DirNode *rootNode; //根节点

  currDir = new DirNode;

  currDir->DirCount = 0;

  rootNode = currDir;

  iNode = new INode;

  AuthorMessage();

  Format(); //初始化

  Linkdisk(); //成组连接

  Init();

  Init(currDir, DIR, "root\\a:\\", iNode, 0);

  while (run)
  {

    help();

    while (true)
    {

      scanf("%d", &command);

      fflush(stdin);

      if (command > 0 && command < 9)

        break;

      cout << "\n命令错误,请重新输入" << endl;

      command = -1;
    }

    switch (command)

    {

    case 1:

      cout << "\n请输入文件名" << endl; //新建问件

      cin >> fileName;

      fflush(stdin);

      cout << "\n请输入文件长度，单位KB" << endl;

      cin >> length;

      fflush(stdin);

      if (length < 0 || length > freeTotalB)
      {

        cout << "文件长度不合法\n"
             << endl;

        break;
      }

      Mf(currDir, fileName, iNode, length);

      break;

    case 2:

      cout << "\n请输入目录名" << endl;

      cin >> dirName;

      Md(currDir, dirName, iNode, 1);

      break;

    case 3:

      cout << "\n请输入打开文件名" << endl; //打开文件

      cin >> fileName;

      Open(currDir, fileName, iNode);

      break;

    case 4:

      cout << "\n请输入删除文件名" << endl; //删除文件

      cin >> fileName;

      Del(currDir, fileName, iNode);

      break;

    case 5: //建立子目录

      cout << "\n请输入目录名" << endl;

      cin >> dirName;

      Rd(currDir, dirName, iNode);

      break;

    case 6:

      Dir(currDir, iNode); //显示当前目录下的信息

      break;

    case 7:

      exit(currDir, iNode); //退出系统

      run = false;

      break;

    case 8:

      system("cls"); //清屏

      break;

    default:

      break;
    }
  }
}